package com.wust.smartcity.common;


import com.wust.smartcity.common.annotations.OperationLog;
import com.wust.smartcity.common.context.DefaultBusinessContext;
import com.wust.smartcity.common.entity.bl.BlOperationLog;
import com.wust.smartcity.common.util.NetworkUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by wust on 2019/5/27.
 */

public abstract class OperationLogAspectBase {


    public void before(JoinPoint jp) throws Throwable {
        Signature sig = jp.getSignature();
        if (sig instanceof MethodSignature) {
            MethodSignature methodSignature = (MethodSignature) sig;
            Method currentMethod = jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());

            Object annotationObj = currentMethod.getAnnotation(OperationLog.class);
            if(annotationObj != null) {
                OperationLog operationLogAnnotation = (OperationLog) annotationObj;
                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                DefaultBusinessContext ctx = DefaultBusinessContext.getContext();
                Object[] args = jp.getArgs();

                BlOperationLog sysOperationLog = new BlOperationLog();
                sysOperationLog.setModuleName(operationLogAnnotation.moduleName().getValue());
                sysOperationLog.setBusinessName(operationLogAnnotation.businessName());
                sysOperationLog.setOperationType(operationLogAnnotation.operationType().getValue());
                sysOperationLog.setOperationIp(NetworkUtil.getIpAddress(request));
                sysOperationLog.setOperationData(parse2string(args));
                sysOperationLog.setSource(getServerName());
                sysOperationLog.setCreaterId(ctx.getAccountId());
                sysOperationLog.setCreaterName(ctx.getAccountName());
                sysOperationLog.setCreateTime(new Date());
                insert(sysOperationLog);
            }
        }
    }

    protected abstract String getServerName();

    protected abstract void insert(BlOperationLog sysOperationLog);


    private String parse2string(Object[] args){
        if(args != null && args.length > 0){
            List<Object> list = new ArrayList();
            for (Object arg : args) {
                if (arg instanceof ServletRequest){
                    continue;
                }
                list.add(arg);
            }
            if(list.size() > 0){
                return list.toString();
            }
        }
        return "";
    }
}
